bool BARecursion(Matrix table, int *s, bool *book, int i, int n, int m) {
    bool result, ret;

    ret = false; /* 初始化返回值为false，即无解 */
    if (i == n) { /* 完成了一组状态的枚举 */
        memset(book, false, sizeof(bool) * m); /* 初始化全为false的数组 */
        result = true;
        for (i = 0; i < n; i++) { /* 检查条件（1）*/
            if (book[s[i]] == false) { /* 若第s[i]本书还没有被分配 */
                book[s[i]] = true; /* 则将之分配给第i个人 */
            } else { /* 若第s[i]本书已经被前面的人分走了 */
                result = false; /* 条件（1）不满足 */
                break;
            }
        }
        if (result == true) { /* 条件（1）满足, 检查条件（2）*/
            for (i = 0; i < n; i++) {
                if (table->t[i][s[i]] != 1) { /* 第 i 个人不喜欢自己分到的书 */
                    result = false;
                    break;
                }
            }
        }
        if (result == true) { /* 条件（1）和（2）都满足 */
            Print(s, n);
            ret = true; /* 返回值为true，即输出了至少一组解 */
        }
    } else {
        for (s[i] = 0; s[i] < m; s[i]++) {
            ret = (BARecursion(table, s, book, i + 1, n, m)
                   || ret); /* 递归后保持真值不变 */
        }
    }
    return ret;
}

void BookAssignment(Matrix table, int n, int m) {
    int *s; /* 解的状态分量 */
    bool *book; /* 书的分配标记 */

    s = (int *)malloc(sizeof(int) * n);
    book = (bool *)malloc(sizeof(bool) * m);
    if (BARecursion(table, s, book, 0, n, m) == false) {
        printf("No Solution\n");
    }
    free(s);
    free(book);
}